need_copy = FALSE;
}
- else
+ else if (!options->force_copy)
{
HardlinkResult hardlink_res = HARDLINK_RESULT_NOT_SUPPORTED;
/* Try to do a hardlink first, if it's a regular file. This also
if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_BARE_USER_ONLY)
options->mode = OSTREE_REPO_CHECKOUT_MODE_USER;
+ g_return_val_if_fail (!(options->force_copy && options->no_copy_fallback), FALSE);
+
g_autoptr(GFile) commit_root = (GFile*) _ostree_repo_file_new_for_commit (self, commit, error);
if (!commit_root)
return FALSE;
static char *opt_from_file;
static gboolean opt_disable_fsync;
static gboolean opt_require_hardlinks;
+static gboolean opt_force_copy;
static gboolean
parse_fsync_cb (const char *option_name,
{ "from-file", 0, 0, G_OPTION_ARG_STRING, &opt_from_file, "Process many checkouts from input file", "FILE" },
{ "fsync", 0, 0, G_OPTION_ARG_CALLBACK, parse_fsync_cb, "Specify how to invoke fsync()", "POLICY" },
{ "require-hardlinks", 'H', 0, G_OPTION_ARG_NONE, &opt_require_hardlinks, "Do not fall back to full copies if hardlinking fails", NULL },
+ { "force-copy", 'C', 0, G_OPTION_ARG_NONE, &opt_force_copy, "Never hardlink (but may reflink if available)", NULL },
{ NULL }
};
* `ostree_repo_checkout_at` until such time as we have a more
* convenient infrastructure for testing C APIs with data.
*/
- if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks || opt_union_add)
+ if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks || opt_union_add || opt_force_copy)
{
OstreeRepoCheckoutAtOptions options = { 0, };
"Cannot specify both --union and --union-add");
goto out;
}
+ if (opt_require_hardlinks && opt_force_copy)
+ {
+ glnx_throw (error, "Cannot specify both --require-hardlinks and --force-copy");
+ goto out;
+ }
else if (opt_union)
options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES;
else if (opt_union_add)
if (subpath)
options.subpath = subpath;
options.no_copy_fallback = opt_require_hardlinks;
+ options.force_copy = opt_force_copy;
if (!ostree_repo_checkout_at (repo, &options,
AT_FDCWD, destination,
set -euo pipefail
-echo "1..65"
+echo "1..66"
$CMD_PREFIX ostree --version > version.yaml
python -c 'import yaml; yaml.safe_load(open("version.yaml"))'
CHECKOUT_U_ARG=""
COMMIT_ARGS=""
DIFF_ARGS=""
-if grep bare-user-only repo/config; then
+if grep -q bare-user-only repo/config; then
# In bare-user-only repos we can only represent files with uid/gid 0, no
# xattrs and canonical permissions, so we need to commit them as such, or
# we end up with repos that don't pass fsck
$OSTREE checkout test2 checkout-test2
validate_checkout_basic checkout-test2
+if grep -q 'mode=bare$' repo/config; then
+ assert_not_streq $(stat -c '%h' checkout-test2/firstfile) 1
+fi
echo "ok checkout"
# Note this tests bare-user *and* bare-user-only
rm checkout-test2 -rf
-if grep bare-user repo/config; then
+if grep -q bare-user repo/config; then
$OSTREE checkout -U -H test2 checkout-test2
else
$OSTREE checkout -H test2 checkout-test2
fi
echo "ok checkout -H"
+rm checkout-test2 -rf
+$OSTREE checkout -C test2 checkout-test2
+for file in firstfile baz/cow baz/alink; do
+ assert_streq $(stat -c '%h' checkout-test2/$file) 1
+done
+
+echo "ok checkout -C"
+
$OSTREE rev-parse test2
$OSTREE rev-parse 'test2^'
$OSTREE rev-parse 'test2^^' 2>/dev/null && fatal "rev-parse test2^^ unexpectedly succeeded!"